home *** CD-ROM | disk | FTP | other *** search
- ;;------------------------------------------------------------------------------
- ;;Filename jimtech.txt
- ;;System
- ;;Author JIM TAYLOR
- ;;Date Wed 3 Sep 1997
- ;;Description Technical programming information for Flying Corps
- ;;------------------------------------------------------------------------------
-
-
- This file describes programming information for the extra files
- provided with Flying corps gold. The following areas are covered:
-
- Keyboard input
-
- Analogue interface
-
- Config file
-
- Mission editor
-
- Please understand that these programming details are extremely brief.
- Quite a bit of additional research will be required by a potential
- programmer. I don't know if anybody will ever actually look at this!
-
- Keyboard input
- ==============
-
- During the 3d sections, the keyboard is mapped into a bit lookup table.
- There is a 1 bit per keyboard scancode lookup which describes wether
- the key is currently pressed. In addition, each key and shift combination
- can be associated with 2 bits in a larger table. See keytest.h.
-
- When a key is pressed, both bits are set if the key is not already
- pressed. When the key is released, only 1 bit is cleared. Within the
- program, these bits are polled, and then the second bit is cleared.
-
- In keymaps.h, the macro Keyname() defines equate names for each bit
- pair.
-
- The mapping of scancodes and shiftkeys to these equates is now driven
- by the binary file FLY\keyboard\keyb3d.bin. By modifying this file,
- the keyboard mapping of the program can be changed.
-
- This file is generated by compiling the table KeyMapping in keymaps.h.
-
- Note that while this system supports 8 shift states only 5 work in
- Windows95 (unshifted, shift, alt, ctrl, and 101key), the 3 RHS shift keys
- are only distinguishable to the DOS program.
-
- Analogue interface
- ==================
-
- Another method of getting input from the program is via the analogue
- interface. This is a set of DLLs which can be automatically loaded by
- the program at runtime via the savegame file.
-
- As well as generating analogue axis inputs which will be recognised by
- the game, these routines can also emulate keyboard events and drive
- output effects for force feedback joysticks, for instance.
-
- We wish to make this interface public so that new devices can be
- supported and further tuning of our interface can take place.
-
- Sources for the existing drivers has been included.
-
- During calibration, the input routine is called once per screen
- refresh, perhaps 5 to 10 times a second. Once the 3d is running it is
- called every 3 centiseconds. We found that the windows driver simply
- stopped the computer if called 33 times a second, so the driver applys
- a stepping down factor.
-
- However, our DOS direct access driver runs far faster even under windows.
-
- Data structure
- --------------
-
- The data structures are in the header file analogue.h
-
- There are 32 instances of Axis, and 8 instances of Device.
-
- The enum AxisUses indexes the axis array.
- MAKEFIELD() produces a bitfield called AxisUsesField.
-
- The instance of this in each Device indicates which axes the device
- will drive. Each device must own at least one axis which is polled by
- the game.
-
- Axis[]:
-
- Note that this structure is 'future proofed' Flying Corps only uses
- 7 of the axes for input, and FCG uses 11:
- flight: elevator, aileron, rudder, throttle, cooliehat
- front: UI_X,UI_Y
- views: head hdg, pitch, roll; zoom
-
-
- Axes 28 to 31 are dummies for DLLs which don't actually generate axis
- values. Devices owning one of these axes are always polled, but the
- results are ignored. Instead, these axes are written to by the program
- so that a force feedback device can respond to the effects.
-
- The axis record contains a number of fields which are intended to hold
- the calibration information for that axis. It is up to the driver to
- make the position field contain a value between -32767, 0, and +32767.
- A disabled or ignored axis returns 32768. In addition, the Throttle is
- ignored for readings of +/-32767.
-
- The signed values centre, min, and max are particularly useful, and I
- also use scale1 and scale2 as multiplication factors. The capitalised
- access functions Min(), Max(), etc. access the same word fields as
- absolute values.
-
- When used to represent feedback, the access functions FB_Lx() are
- intended to represent linear effects, and the functions FB_Rx()
- represent rotational effects. When the value is actually changed by
- the game, position will be set non-zero.
-
- In addition, the Axis record contains indexes to the "rowan text
- system" for printing calibration messages, and the status field
- indicates any errors during calibration.
-
- The equates for these texts are in text.h. A number of spares have been
- prepared starting at JOYSTIC_SPARE_2. Alternate text can be poked into
- the existing binary text files. See the english\text directory, and look for
- "DeviceNameSpare2DeviceNameSpare2" etcetera.
-
- The first 8 entries from JOYSTICK_DEVICE_NAME to JOYSTIC_SPARE_6 are
- printed in the driver selection list, and map directly to the order of
- the files in the file libcode\dir.dir. All the spares after 6 are
- unassigned.
-
- Device[]:
-
- As well as the "activeaxes" field which lists which axes the device
- will update and the "rowan text system" device name, which is actually
- used to identify the curent driver on the calibration screen, a small ammount of
- workspace is provided in the LastButtons field.
-
- The STUBLOADABLE and devfile are used to manage the loading of the
- driver, so should not be altered at runtime.
-
- Code interface
- ==============
-
- Initial loading of the driver code involves making a C++ virtual
- function table to access the Device member functions.
-
- In MS-DOS this is done by the main program. It matches the routines
- listed in analpub.cpp and creates a new table. The exact order and size
- of this list in analpub is critical.
-
- In Windows, the DEVICEHOOK() routine in the DLL provides this facility.
-
- These two interfaces can be used simultaniously, and are: ANALJOY.BIN.
-
- In both cases, a compilation datestamp is checked to ensure compatibility
- between the main program and the DLL. This will have to be modified in
- the DLLs to match the date the main program was last compiled.
-
- Unlike the traditional Windows COM, the main program owns the Device
- instances, and is able to store useful data in them.
-
- In MS-DOS, the DLL has no access to any data or functions except those
- provided as parameters. Any further facilities required must be managed
- independently through the DPMI interrupt INT31. Any handles or pointers
- can be held in the LastButtons field.
- The 5K low memory data area workspace is passed to all the functions
- (except close()) for use as required. The contents are not guaranteed
- between calls, but the address is.
- In windows, the DLL has full access to all system functions and data areas
- as normal.
-
- The following member functions are required:
-
- Bool Initialise(UByte*const workspace,Axis axes[]);
- -allows the DLL to set itself up.
-
- Bool LoadGame(UByte*const workspace,Axis axes[]);
- -called after the savegame record has been loaded
-
- Bool CloseDown(UByte*const workspace);
- -called before the driver is removed from memory
-
- void PreCalib(UByte*const workspace,Axis axes[],axisconfigpages& pages);
- -called on beginning to calibrate the joystick.
- activeaxes has been filled in with required options.
- The routine can initialise any axes it will be calibrating.
- The routine fills in pages. This is a list of 4 axis indexes
- per page displayed during configuration.
- The normal configuration processes 4 axes at once on 1 page,
- but you can force the display to be repeated up to 5 times.
- If no axes are nabled on the first page then configuration is
- skipped. This can be done if you trust the standard windows joystick
- configuration, or if your device returns fixed values anyway.
-
- Bool CalibCenter(UByte*const workspace,Axis axes[],const AxisUsesField& reqaxes);
- Bool CalibExtreme(UByte*const workspace,Axis axes[],const AxisUsesField& reqaxes);
- -These two routines are called continuously during the two
- calibration phases.
- For each axis flagged in reqaxis, the corresponding axes[].position
- should be filled in with estimates of the joystick position
- in the range -32K to +32K.
- Simultaniously, the values read should be used to calibrate the
- joystick, and the status should be set to indicate the
- progress.
- When the phase is over they simply cease to be called, and
- each axis's status field is checked. There is no "phase over" routine.
- They can cause calibration to cease by setting their return code true,
- indicating that a button on the stick was pressed.
-
-
- Bool ReadPosition(UByte*const workspace,Axis axes[],const AxisUsesField& reqaxes,keytests* keyboard);
- -This is the main joystick workhorse.
- Position values should be provided for all the reqaxes, but
- others can be filled in as well. Then, when these are requested
- the routine would return quickly.
-
- The keyboard routine gives access to the keyboard class
- instance, and pointers to routines to set and clear keys by
- their rowan key indexes rather than the scancodes.
-
-
- Additionally, the following prototypes are provided as templates for
- writing your routines. You don't have to use them, but I'd advise it:
-
- Bool ReadHWPos(UByte*const workspace,Axis axes[],const AxisUsesField& reqaxes,ULong* newbuttons);
- -gets raw values into the position fields
- Bool ScaleHWPos(UByte*const workspace,Axis axes[],const AxisUsesField& reqaxes);
- -converts the raw values into +/-32K
- Bool ReadButtons(UByte*const workspace,Axis axes[],const AxisUsesField& reqaxes,ULong* newbuttons,keytests* keyboard);
- -processes the buttons into key presses
-
- Compiling
- ---------
-
- I compile and link these programs using Watcom C++ ver 10.5. You are
- welcome to use whatever you like, but you may have problems with the
- optimisation of the analpub.cpp module which is used to interface with
- MS-DOS.
-
- Compile the analpub fully optimised and it turns into a series of jmp
- statements. Compile the main code module with stack checking turned
- off. Link analpub, then the main module, then any libraries you need.
-
- In MS-DOS only code between "ROWANLIB" markers will be loaded in. These
- markers are emitted into the code segment. See stub.m for more detail.
-
- The binaries generated live in the LIBCODE directory. They are
- referenced by the DIR.DIR file in that directory.
- This is the C type "char [][16];"
-
- There is a lot more information in the various header files.
-
- Config File
- ===========
-
- The main config file is savegame\settings.cfg and savegame\winset.cfg
- for windows.
-
- This file contains 3 elements:
-
- 1) A zero terminated date string which is compared with the main
- executable's date
-
- 2) The structure SaveData (savegame.h) which controls a wide number of
- effects
-
- 3) The structure Analogue (analogue.h) which contains all 8 devices and
- all 32 axes.
-
- In particular, the devices[] contain a word devfile field which identifies the
- DLL file to load. If zero that driver is not loaded, but if set to a
- certain value, this indicates the location of the DLL.
- The upper byte identifies the directory by accessing the COMMON.DIR
- file. LIBCODE is directory 201. The lower byte indexes the DIR.DIR file
- inside the directory.
-
- The displayed joystick is Devices[0]
- In MS-DOS the mouse input is drive by Devices[1]
- In windows the mouse input is handled by winmain.
-
- By directly modifying the savegame file before running the program,
- additional drivers can be made to load.
-
-
- Mission Editor
- ==============
-
- The mission editor provided with FCG is by no means comprehensive. If
- you should decide that you have nothing better to do for a few months,
- then you could try to do better.
-
- The basic feature of the mission editor is that it generates a textfile
- which is then compiled by the utility MAKEBFW.EXE. However, it reads in
- the binary file generated by MAKEBF. There is only ever one user
- generated source file in the usersrc directory.
-
- While the mission editor is unable to allow certain advanced features
- to be directly edited, these features should be preserved as a
- "complex" expression. These expressions are described in bfnumber.h.
- Note that while bfnumber is an internal representation of an expression
- the structure does not exactly mirror the binary files generated by
- MAKEBFW.
-
- MAKEBFW.EXE actually reads bfields\initial.res and then attempts to
- compile bfields\battle.src which contains the source for all the
- battlefields for the original campaigns, but because
- they are unchanged it then generates just one user battlefield.
-
- The actual syntax is:
-
- MAKEBFW bfields\initial.res bfields\battle.src
-
- Optionally, "-M" stops uidvals.g from being generated (destroyed), OR "."
- generates the file textfour.err in directory ".".
-
- Textfour.err shows the internal tree structure built by MAKEBFW, and is over
- 14MB long. Generating it also quadrouples the duration of MAKEBFW.
-
- The basic structure stored to disk is made up of command byte/child
- count byte pairs. The command bytes are listed in makebf.h.
-
- The mission editor is able to communicate with the main game via the
- scratchpad. It can send "MED: directory file" or "MED: directory".
-
- If the main program doesn't delete this message with a few seconds then
- it is launched again.
-
- The mission editor also supports a command-line interface to decompile
- one battlefield back into usersrc\custom.bfi:
-
- meditor directory\file.bf
-
- The Family statement in the custom mission is generated by the
- following fprint statement:
-
- fprintf(f,
- "%i %i "
- "%hi %hi "
- "%c %c "
- "%hi %hi %hi "
- "%hi %hi %hi "
- "%hi %hi "
- "%hi %hi "
- "%hi %hi %hi "
- ,
- missiondate,timeofday,
- numofsquadronac,numofflightac,
- PlayerNationality+'@',formationtypeindex+'@',
- weathernum,windspeed,winddirection,
- era,region,PlayerAcType,
- PlayerHomeBase,EnemyHomeBase,
- MainObjective,SubObjective,
- WP1,WP2,WP3
- );
-
- The second description is the news.
-
- The main game considers all directories beginning with "M" to be mission
- groups, plus "default"; all that begin with "C" are campaigns.
-
- The dictionary system in MAKEBFW is unable to cope with filenames that
- start with digits.
-
- In a campaign directory, the dir.dir offers access to the campaign
- initialisation data as index 251, and the pilots as 252.
-
- The entries 1..250 form the sequential missions for the campaign.
-
- The campaign structure is in mecamp.h
- The pilots are each:
-
- struct PilotType
- {
- TextRef name; /word filled at runtime
- SkillType skill; /byte
- pilotstatus status; /byte
- CharacterType character; /byte
- MoraleType morale; /byte
- NextFollAct nextfollact; /byte
- SWord dayssincerest;
- SWord kills;
- SWord daystorecover;
- struct ImageMaps
- {
- UByte topwing;
- UByte tail;
- UByte btmwing;
- UByte fuselage;
- UByte other;
- UByte emblem;
- } imagemaps;
- };
-
- followed by a 50 byte name field.
-
- The mission editor is unable to modify the main world. This is
- specified by the region as a rowan file number. The upper byte
- specifies the directory number, and the lower byte is the index in
- dir.dir.
-
- Additional base worlds could be saved in the campaign directory by
- counting backwards from 250. Unfortunately, a directory may only
- contain 254 files maximum including dir.dir at position 0.
-
- UniqueIDs
- ---------
-
- The location of objects is driven by uniqueids. In makebf, an object
- can be placed with only a umiqueid band. At runtime such objects will
- be allocated uniqueids within that band sequentially. The bands are
- listed in uniqueid.h
-
- However, if the object is referenced either within the MAKEBFW system, or
- by the main program, then it will be assigned a permanent uniqueID
- within it's band by MAKEBFW. MAKEBFW assigns these downward from the
- top of the band, but as far as the runtime game is concerned they are
- cast in stone in uidvals.g, which MAKEBFW outputs.
-
- The same object can exist in different base era files by applying the
- same SetUID instruction in both items.
-
- Needless to say, every object should get a unique uniqeid. If two
- objects with the same UID are loaded, or a band overflows the game
- will emit an error message and stop.
-
- This is particularly a problem in events, where complex waypoints
- positions often refer to each other forcing MAKEBFW generate a
- permanent uid. This event then cannot be loaded twice in the same
- mission.
-
- One important feature of MAKEBFW is that it can forward-reference within
- the source. However, it sometimes needs help to decide what type a
- symbol is. If it guesses wrong then it will generate an error on
- reaching the actual definition.
-
- MAKEBFW only generates one error message and then stops. Press a key to
- exit.
-
-
- /Jim
-
-